//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <ddk.h>

class UnregDevice : public CDeviceDriver
{
public:
    CARAPI Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ EzByteBuf buffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ EzByteBuf buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ EzByteBuf inBuffer,
        /* [out] */ EzByteBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    virtual void Dispose() {}
};

EXTERN IDeviceDriver * CDECL CreateUnregDevice(uint_t uDeviceNo,
    void *pvParameter)
{
    UnregDevice *pDriver = new UnregDevice;
    if (NULL == pDriver) {
        kprintf("ERROR:There have no enough memory, %s, %d\n",
                        __FILE__, __LINE__);
        return NULL;
    }

    pDriver->AddRef();

    return pDriver;
}

ECode UnregDevice::Read(
    /* [in] */ Int64 u64Offset,
    /* [in] */ Int32 bytesToRead,
    /* [out] */ EzByteBuf buffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode UnregDevice::Write(
    /* [in] */ Int64 u64Offset,
    /* [in] */ EzByteBuf buffer,
    /* [out] */ Int32 * pBytesWritten,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode UnregDevice::Control(
    /* [in] */ Handle32 nControlCode,
    /* [in] */ EzByteBuf inBuffer,
    /* [out] */ EzByteBuf * pOutBuffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    // For multi-threads unregister different device,
    // register these devices first
    if (nControlCode >= 11000) {
        return DzRegisterDevice(L"unregdev01", nControlCode - 10000, NULL);
    }

    // For multi threads unregister different device
    if (nControlCode >= 1000) {
        return DzUnregisterDevice(L"unregdev01", nControlCode);
    }

    switch (nControlCode) {
        // Unregister device registered statically, and device NO. is NONE
        case 1:
            return DzUnregisterDevice(L"unregdev01", DEVICENO_NONE);

        // Unregister device registered statically, and device NO. is zero
        case 2:
            return DzUnregisterDevice(L"unregdev01", 0);

        // register one device
        case 3:
            return DzRegisterDevice(L"unregdev01", 3, NULL);

        // unregister the device registered in 3
        case 4:
            return DzUnregisterDevice(L"unregdev01", 3);

        // The length of device name is 31 -- register
        case 5:
            return DzRegisterDevice(L"lengthofdevicename000000equal31",
                            25, NULL);

        // The length of device name is 31 -- unregister
        case 6:
            return DzUnregisterDevice(L"lengthofdevicename000000equal31", 25);

        // The length of device name is 32
        case 7:
            return DzUnregisterDevice(L"abcdefghijklmnopqrstuvwxyz123456",
                            DEVICENO_NONE);

        // Unregister device never registered
        case 8:
            return DzUnregisterDevice(L"unregdev01", 8);

        // Register one device
        case 9:
            return DzRegisterDevice(L"unregdev01", 9, NULL);

        // Unregister device registered in 9,
        //(client repeats to call, multiple threads unregister same device)
        case 10:
            return DzUnregisterDevice(L"unregdev01", 9);

        // (register one device)
        case 11:
            return DzRegisterDevice(L"unregdev01", 11, NULL);

        // Unregister device registered in 11
        // (When device is being used, call it)
        case 12:
            return DzUnregisterDevice(L"unregdev01", 11);

        // Repeat to register device "unregdev02".
        // This device has been register
        // statically, but don't specify CreateXXX function in DriverConfig table
        case 13:
            return DzRegisterDevice(L"unregdev02", DEVICENO_NONE, NULL);

        case 14:
            return DzRegisterDevice(L"unregdev02", 14, NULL);

        default:
            return E_NOT_IMPLEMENTED;
    }
}
